<?php

/**
 * Swift Mailer Wrapper
 * @package Nina
 * @author John Main
 */
class Nina_Mail
{
	/**
	 * Message headers
	 * @access protected
	 * @var array
	 */
	protected $headers = array();

	/**
	 * Message recipients
	 * @access protected
	 * @var array
	 */
	protected $recipients = array('to' => array(), 'cc' => array(), 'bcc' => array());

	/**
	 * Message object
	 * @access protected
	 * @var Swift_Message
	 */
	protected $message;

	/**
	 * Is this an HTML email?
	 * @access protected
	 * @var boolean
	 */
	protected $html = true;

	/**
	 * Constructor
	 * @param string [$title=''] Title
	 * @param boolean [$html=true] HTML email
	 * @param string [$charset='utf8'] Character set
	 */
	public function __construct($title = '', $html = true, $charset = 'utf8') {
		require_once NINA_ROOT.DIRECTORY_SEPARATOR.'swift'.DIRECTORY_SEPARATOR.'lib'.DIRECTORY_SEPARATOR.'swift_required.php';
		
		$this->message = Swift_Message::newInstance();
		$this->message->setCharset($charset);
		$this->html = $html;

		$html ? $this->addHeader('Content-Type', 'text/html', array('charset' => $charset)) : $this->addHeader('Content-Type', 'text/plain', array('charset' => $charset));

		if($title)
			$this->setTitle($title);
	}
	
	/**
	 * Set the message title
	 * @param string $title The title
	 */
	public function setTitle($title) {
		$this->message->setSubject($title);
	}

	/**
	 * Get the message title
	 * @return string
	 */
	public function getTitle() {
		$this->message->getSubject();
	}
	
	/**
	 * Set the 'from' information
	 * @param string $name The name
	 * @param string $email The email
	 * @param boolean $reply_to Also use this as the 'reply to' address
	 */
	public function setFrom($name, $email, $reply_to = true) {
		$this->message->setFrom(array($email => $name));
		
		if($reply_to)
			$this->setReplyTo($name, $email);	
	}
	
	/**
	 * Set the 'reply to' information
	 * @param string $name The name
	 * @param string $email The email
	 */
	public function setReplyTo($name, $email) {
		$this->message->setReplyTo(array($email => $name));
	}
	
	/**
	 * Set the message
	 * @param string $message The message
	 */
	public function setMessage($message) {
		$format = $this->html ? 'text/html' : 'text/plain';
		$this->message->setBody($message, $format);
	}

	/**
	 * Get the message
	 * @return string
	 */
	public function getMessage() {
		return $this->message->getBody();
	}
	
	/**
	 * Add a header
	 * @param string $type The header type
	 * @param string $value The header value
	 * @param array $parameters Any additional parameters
	 */
	public function addHeader($type, $value, $parameters = array()) {
		$this->headers[$type] = array($value, $parameters);
	}
	
	/**
	 * Set the headers
	 * @param array $headers The set of headers
	 */
	public function setHeaders($headers) {
		$this->headers = $headers;
	}
	
	/**
	 * Clear the headers
	 */
	public function clearHeaders() {
		$this->headers = array();
	}
	
	/**
	 * Add a recipient
	 * @param string $email The email address
	 * @param string $name The name
	 */
	public function addRecipient($email, $name = null) {
		if($name)
			$this->message->addTo($email, $name);
		else
			$this->message->addTo($email);
	}
	
	/**
	 * Add a CC recipient
	 * @param string $email The email address
	 * @param string $name The name
	 */
	public function addRecipientCC($email, $name = null) {
		if($name)
			$this->message->addCc($email, $name);
		else
			$this->message->addCc($email);
	}

	/**
	 * Add a BCC recipient
	 * @param string $email The email address
	 * @param string $name The name
	 */
	public function addRecipientBCC($email, $name = null) {
		if($name)
			$this->message->addBcc($email, $name);
		else
			$this->message->addBcc($email);
	}
	
	/**
	 * Render the headers
	 */
	protected function renderHeaders() {
		
		$header_set = $this->message->getHeaders();
		
		foreach($this->headers as $name => $header_data) {
			
			list($value, $parameters) = $header_data;

			if($parameters) {
				$header_set->addParameterizedHeader($name, $value, $parameters);
			}
			else {
				$header_set->addTextHeader($name, $value);
			}
		}
	}
	
	/**
	 * Create the mailer object
	 * @return Swift_Mailer
	 */
	protected function createMailer() {
		$reg = Nina_Registry::getInstance();
		
		$port = ($reg->get('mail.port')) ? $reg->get('mail.port') : 25;

		if ($reg->get('mail.smtp_server')) {
			//Use SMTP
			$transport = Swift_SmtpTransport::newInstance($reg->get('mail.smtp_server'), $port);
			
			if($reg->get('mail.username') && $reg->get('mail.password')) {
				$transport->setUsername($reg->get('mail.username'));
				$transport->setPassword($reg->get('mail.password'));
			}
		}
		elseif($reg->get('mail.sendmail_path')) {
			//Use sendmail
			$transport = Swift_SendmailTransport::newInstance($reg->get('mail.sendmail_path'));
		}
		else {
			//Use Mail
			$transport = Swift_MailTransport::newInstance();
		}
		
		return Swift_Mailer::newInstance($transport);
	}
	
	/**
	 * Send the email
	 * @return integer|boolean
	 */
	public function send() {
		$this->renderHeaders();

		try {
			$mailer = $this->createMailer();
			return $mailer->send($this->message);
		}
		catch(Swift_SwiftException $e) {
			$logger = Nina_Logger::getInstance();
			$logger->error($e->getMessage());

			Nina_Message::doAdd('The mail could not be sent. Please contact your system administrator.');
			return false;
		}
	}
}	